/**
 * Copyright (C) 2013 Bohan
 *
 * This file is part of the Java SACNR API.
 *
 * Java SACNR API is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Java SACNR API is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package bohan.sacnr.api;

import bohan.sacnr.exception.ItemNotFoundException;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.MalformedURLException;

/**
 *
 * @author Bohan
 */
public final class MoneyStats
{

    private final int playerID;
    private final long updated;
    private final String netWorth, cashEarned, cashSpent, medFeePaid;
    private final String[] cashGiven, cashReceived, refueled, foodPurchased,
            weaponsPurchased, moneyBagsFound;

    public MoneyStats(int playerID) throws IOException
    {
        this.playerID = playerID;
        String data;
        try
        {
            URL page = new URL("http://sacnr.com/pstats/" + playerID + "/Money");
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(page.openStream()));

            StringBuilder sb = new StringBuilder(1000);
            while ((data = in.readLine()) != null)
                sb.append(data);
            in.close();
            updated = System.currentTimeMillis();
            data = sb.toString();
        } catch (MalformedURLException e)
        {
            /**
             * This exception should not occur, but in case it does, re-wrap it
             * and throw as a RunTimeException
             */
            throw new RuntimeException("MalformedURLException: " + e.getMessage(), e);
        }

        if (data.indexOf("Invalid user") >= 0)
            throw new ItemNotFoundException("The player with id "
                    + playerID + " was not found.");

        int index;

        if ((index = data.indexOf("Net worth:</th><td>") + 19) >= 19)
            netWorth = data.substring(index, data.indexOf('<', index));
        else
            throw new IllegalArgumentException(Player.EXCEPTION_MESSAGE);

        if ((index = data.indexOf("Cash earned:</th><td>", index) + 21) >= 21)
            cashEarned = data.substring(index, data.indexOf('<', index));
        else
            throw new IllegalArgumentException(Player.EXCEPTION_MESSAGE);

        if ((index = data.indexOf("Cash spent:</th><td>", index) + 20) >= 20)
            cashSpent = data.substring(index, data.indexOf('<', index));
        else
            throw new IllegalArgumentException(Player.EXCEPTION_MESSAGE);

        if ((index = data.indexOf("Medical fees paid:</th><td>", index) + 27) >= 27)
            medFeePaid = data.substring(index, data.indexOf('<', index));
        else
            throw new IllegalArgumentException(Player.EXCEPTION_MESSAGE);

        if ((index = data.indexOf("Times cash given:</th><td>", index) + 26) >= 26)
        {
            cashGiven = new String[2];
            cashGiven[0] = data.substring(index, index = data.indexOf('(', index)).trim();
            index++;
            cashGiven[1] = data.substring(index, data.indexOf(')', index));
        } else
            throw new IllegalArgumentException(Player.EXCEPTION_MESSAGE);

        if ((index = data.indexOf("Times cash received:</th><td>", index) + 29) >= 29)
        {
            cashReceived = new String[2];
            cashReceived[0] = data.substring(index, index = data.indexOf('(', index)).trim();
            index++;
            cashReceived[1] = data.substring(index, data.indexOf(')', index));
        } else
            throw new IllegalArgumentException(Player.EXCEPTION_MESSAGE);

        if ((index = data.indexOf("Times refueled:</th><td>", index) + 24) >= 24)
        {
            refueled = new String[2];
            refueled[0] = data.substring(index, index = data.indexOf('(', index)).trim();
            index++;
            refueled[1] = data.substring(index, data.indexOf(')', index));
        } else
            throw new IllegalArgumentException(Player.EXCEPTION_MESSAGE);

        if ((index = data.indexOf("Times purchased food:</th><td>", index) + 30) >= 30)
        {
            foodPurchased = new String[2];
            foodPurchased[0] = data.substring(index, index = data.indexOf('(', index)).trim();
            index++;
            foodPurchased[1] = data.substring(index, data.indexOf(')', index));
        } else
            throw new IllegalArgumentException(Player.EXCEPTION_MESSAGE);

        if ((index = data.indexOf("Times purchased weapons:</th><td>", index) + 33) >= 33)
        {
            weaponsPurchased = new String[2];
            weaponsPurchased[0] = data.substring(index, index = data.indexOf('(', index)).trim();
            index++;
            weaponsPurchased[1] = data.substring(index, data.indexOf(')', index));
        } else
            throw new IllegalArgumentException(Player.EXCEPTION_MESSAGE);

        if ((index = data.indexOf("Money bags found:</th><td>", index) + 26) >= 26)
        {
            moneyBagsFound = new String[2];
            moneyBagsFound[0] = data.substring(index, index = data.indexOf('(', index)).trim();
            index++;
            moneyBagsFound[1] = data.substring(index, data.indexOf(')', index));
        } else
            throw new IllegalArgumentException(Player.EXCEPTION_MESSAGE);
    }

    /**
     * 
     * @return The time since this player's money stats was last updated in 
     * milliseconds
     */
    public long getAge()
    {
        return System.currentTimeMillis() - updated;
    }

    public int getPlayerID()
    {
        return this.playerID;
    }

    public String getNetWorth()
    {
        return this.netWorth;
    }

    public String getCashEarned()
    {
        return this.cashEarned;
    }

    public String getCashSpent()
    {
        return this.cashSpent;
    }

    public String getMedicalFeesPaid()
    {
        return this.medFeePaid;
    }

    /**
     * Gets the time and amount of cash this player has given. Returns A
     * <code>String</code> array with times cash given at index 0,
     * amount of cash given at index 1. Index 0 is readily Integer parse-able
     * @return A <code>String</code> array representing cash given.
     */
    public String[] getCashGiven()
    {
        return this.cashGiven;
    }

    public String[] getCashReceived()
    {
        return this.cashReceived;
    }

    public String[] getFoodPurchased()
    {
        return this.foodPurchased;
    }

    public String[] getWeaponsPurchased()
    {
        return this.weaponsPurchased;
    }

    public String[] getMoneyBagsFound()
    {
        return this.moneyBagsFound;
    }
    
        /**
     * Creates a new instance of <code>MoneyStats</code> object with updated
     * money stats *EXPENSIVE*.
     * <p>
     * Note that since <code>MoneyStats</code> is an immutable class,
     * this method does not update the current <code>MoneyStats</code>
     * instance, but returns a new updated instance of 
     * <code>MoneyStats</code> object. 
     * <p>
     * Note that this method is always expensive, as it connects to the sacnr 
     * website to update the player's general stats.
     * @return An up to date <code>MoneyStats</code> object.
     * @throws IOException Thrown from the <code>MoneyStats</code>
     * constructor when it can't connect to the server.
     * @see MoneyStats#MoneyStats(int) 
     */
    public MoneyStats update() throws IOException
    {
        return new MoneyStats(playerID);
    }
}
